package com.canyou.utils;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

/**
 * request帮助类
 *
 * @author fy
 * @date 2017-08-03
 */
public final class RequestUtils {

    private RequestUtils() {
    }

    /**
     * 客户端请求来源请求头
     */
    private static final String REFERER_HEADER = "Referer";

    /**
     * 用户使用的客户端请求头
     */
    private static final String USER_AGENT_HEADER = "User-Agent";

    /**
     * 客户端接收的响应类型请求头
     */
    private static final String ACCEPT_HEADER = "Accept";

    /**
     * 授权信息头
     */
    private static final String AUTHORIZATION_HEADER = "Authorization";

    /**
     * ajax 请求头
     */
    private static final String AJAX_HEADER = "X-Requested-With";

    /**
     * ajax请求头的值
     */
    private static final String AJAX_HEADER_VALUE = "XMLHttpRequest";

    /**
     * json 请求 响应头
     */
    private static final String JSON_CONTENT_TYPE = "application/json";

    /**
     * web默认端口
     */
    private static final List<Integer> DEFAULT_PORTS = Arrays.asList(80, 443);

    /**
     * ie agent header
     */
    private static final String[] IE_BROWSER_SIGNALS = {"MSIE", "Trident", "Edge"};

    /**
     * 客户端请求源
     *
     * @param request
     * @return
     */
    public static String referer(HttpServletRequest request) {
        return request.getHeader(REFERER_HEADER);
    }

    /**
     * 用户请求使用的客户端标识
     *
     * @param request
     * @return
     */
    public static String userAgent(HttpServletRequest request) {
        return request.getHeader(USER_AGENT_HEADER);
    }

    /**
     * 客户端接收的响应类型
     *
     * @param request
     * @return
     */
    public static String accept(HttpServletRequest request) {
        return request.getHeader(ACCEPT_HEADER);
    }

    /**
     * 获取认证头信息
     *
     * @param request
     * @return
     */
    public static String authorization(HttpServletRequest request) {
        return request.getHeader(AUTHORIZATION_HEADER);
    }

    /**
     * 解决获取scheme的问题, 在使用nginx代理时scheme会丢失,
     * 需要在nginx上配置: proxy_set_header X-Forwarded-Proto $scheme;
     *
     * @param request
     * @return
     */
    public static String scheme(HttpServletRequest request) {
        String scheme = request.getHeader("x-forwarded-proto");
        if (StringUtils.isNotBlank(scheme)) {
            return scheme;
        }
        return request.getScheme();
    }

    /**
     * 获取请求发起的host名, nginx 默认会吧RemoteHost放到Origin字段
     *
     * @param request
     * @return
     */
    public static String clientHost(HttpServletRequest request) {
        String clientHost = request.getHeader("origin");
        if (StringUtils.isNotBlank(clientHost)) {
            return UrlUtils.getHost(clientHost);
        }
        return request.getRemoteHost();
    }

    /**
     * 判断当前请求是否是ajax请求
     *
     * @param request
     * @return
     */
    public static boolean isAjaxRequest(HttpServletRequest request) {
        String ajaxHeader = request.getHeader(AJAX_HEADER);
        if (StringUtils.isNotBlank(ajaxHeader) && AJAX_HEADER_VALUE.equalsIgnoreCase(ajaxHeader)) {
            return true;
        }
        return false;
    }

    /**
     * 当前请求是否是json格式的传参
     *
     * @param request
     * @return
     */
    public static boolean isJsonContentType(HttpServletRequest request) {
        String contentType = request.getContentType();
        if (StringUtils.isNotBlank(contentType) && contentType.contains(JSON_CONTENT_TYPE)) {
            return true;
        }
        return false;
    }

    /**
     * 客户端是否接受json格式的响应类型
     *
     * @param request
     * @return
     */
    public static boolean acceptJson(HttpServletRequest request) {
        String accept = accept(request);
        if (StringUtils.isNotBlank(accept) && accept.contains(JSON_CONTENT_TYPE)) {
            return true;
        }
        return false;
    }

    /**
     * 判断请求是否在微信内置浏览器中发起
     *
     * @param request
     * @return
     */
    public static boolean isInWxBrowser(HttpServletRequest request) {
        String userAgent = userAgent(request);
        if (StringUtils.isNotBlank(userAgent) && RegexUtils.match(RegexUtils.WX_BROWSER, userAgent)) {
            return true;
        }
        return false;
    }

    /**
     * 请求是否是在本域发起
     *
     * @param request
     * @return
     */
    public static boolean isInDomainRequest(HttpServletRequest request) {
        String referer = referer(request);
        String host = clientHost(request);
        if (StringUtils.isBlank(referer) || StringUtils.isBlank(host)) {
            return false;
        }
        String refererHost = UrlUtils.getHost(referer);
        if (StringUtils.isBlank(refererHost) || !refererHost.equalsIgnoreCase(host)) {
            return false;
        }
        return true;
    }

    /**
     * 获取根url
     *
     * @param request
     * @return
     */
    public static String rootUrl(HttpServletRequest request) {
        String rootUrl = RequestUtils.scheme(request) + "://" + request.getServerName();
        int serverPort = request.getServerPort();
        if (!DEFAULT_PORTS.contains(serverPort)) {
            rootUrl += ":" + serverPort;
        }
        String contextPath = request.getContextPath();
        if (StringUtils.isNotBlank(contextPath)) {
            rootUrl += "/" + contextPath;
        }
        return rootUrl;
    }

    /**
     * 判断是否是IE浏览器
     *
     * @param request
     * @return
     */
    public static boolean isMsBrowser(HttpServletRequest request) {
        String userAgent = userAgent(request);
        for (String signal : IE_BROWSER_SIGNALS) {
            if (userAgent.contains(signal)) {
                return true;
            }
        }
        return false;
    }

}
